﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LGPeWJNM.BaseClasses
{
    /// <summary>
    /// Ponto do plano cartesiano
    /// </summary>
    public class Point : IEquatable<Point>, IComparable<Point>
    {
        /// <summary>
        /// Abscissa
        /// </summary>
        [System.Xml.Serialization.XmlAttribute]
        public double X { get; set; }

        /// <summary>
        /// Ordenada
        /// </summary>
        [System.Xml.Serialization.XmlAttribute]
        public double Y { get; set; }

        /// <summary>
        /// Retorna uma representação em string dos valores contidos nesse ponto para fácil leitura
        /// </summary>
        /// <returns>a seguinte string {X={0},Y={1}} onde {0} e {1} são representações conforme a conversão de interos em string</returns>
        public override string ToString()
        {
            return string.Format("X={0},Y={1}", X, Y);
        }

        /// <summary>
        /// Determina a distância entre dois pontos
        /// </summary>
        /// <remarks>A distância é calculada pela raiz quadrada da soma dos quadrados das diferenças de cada coordenada</remarks>
        /// <param name="p1">qualquer ponto do plano cartesiano</param>
        /// <param name="p2">outro qualquer ponto do plano cartesiano</param>
        /// <returns>a distancia entre os pontos em precisão flutuante</returns>
        public static double operator %(Point p1, Point p2)
        {
            double X = p1.X - p2.X;
            double Y = p1.Y - p2.Y;
            return Math.Sqrt(X * X + Y * Y);
            //return Math.Sqrt(Math.Pow((p1.X - p2.X), 2) + Math.Pow((p1.Y - p2.Y), 2));
        }

        /// <summary>
        /// Distância entre o ponto atual e outro especificado
        /// </summary>
        /// <param name="other">outro qualquer ponto do plano cartesiano</param>
        /// <returns>a distancia entre os pontos em precisão flutuante</returns>
        public double Distancia(Point other)
        {
            return this % other;
        }

        /// <summary>
        /// Verifica se as coordenadas de um ponto são coincidentes com outro
        /// </summary>
        /// <param name="other">outro qualquer ponto do plano cartesiano</param>
        /// <returns>retorna 'true' se ambos os pontos tiverem mesma abscissa e ordenada, retorna 'false' caso contrário</returns>
        public bool Equals(Point other)
        {
            return this.X == other.X && this.Y == other.Y;
        }

        /// <summary>
        /// Compara a distância à origem entre dois pontos, para ordená-los.
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(Point other)
        {
            return Convert.ToInt32(other % new Point() { X = 0, Y = 0 } * 100 - this % new Point() { X = 0, Y = 0 });
        }
    }
}